package DuplexLinkList

import "fmt"

type Object interface {

}

type DuplexNode struct {
	Data Object
	PreData *DuplexNode
	NextData *DuplexNode
}

type DuplexLinkList struct {
	Head *DuplexNode
	Tail *DuplexNode
	Size uint
}

//在链尾追加节点
func (linkList *DuplexLinkList) Append(node *DuplexNode) bool{
	if node==nil{
		return false
	}

	if linkList.Size==0 {
		linkList.Head = node
	}else{
		node.PreData = linkList.Tail
		linkList.Tail.NextData = node
	}
	linkList.Tail = node
	linkList.Size++
	return true
}

//插入节点
func (linkList *DuplexLinkList) Insert(node *DuplexNode,index uint) bool{
	if linkList.Size==0 || node==nil || index>linkList.Size {
		return false
	}

	if index==0 {
		node.NextData = linkList.Head
		linkList.Head.PreData = node
		linkList.Head = node
	}else{
		tempNode := linkList.Head
		for i:=uint(1);i<index ;i++  {
			tempNode = tempNode.NextData
		}
		node.PreData = tempNode
		node.NextData = tempNode.NextData
		tempNode.NextData.PreData = node
		tempNode.NextData = node

		if linkList.Size==index {
			linkList.Tail = node
		}
	}
	linkList.Size++
	return true
}

//通过下标删除节点
func (linkList *DuplexLinkList) Delete(index uint)bool{
	if index>=linkList.Size {
		return false
	}
	if index == 0{
		linkList.Head = linkList.Head.NextData
		linkList.Head.PreData=nil
	}else{
		preNode := linkList.Head
		for i:=uint(1);i<index ; i++ {
			preNode = preNode.NextData
		}
		node := preNode.NextData
		preNode.NextData = node.NextData

		if index == linkList.Size-1 {
			linkList.Tail = preNode
		}else{
			node.NextData.PreData = preNode
		}
		node.PreData = nil
		node.NextData = nil
	}
	linkList.Size--
	return true
}

//获取下标节点
func (linkList *DuplexLinkList) Get(index uint) *DuplexNode{
	if index>=linkList.Size {
		return nil
	}
	node := linkList.Head
	for i:=uint(1);i<=index ; i++ {
		node = node.NextData
	}
	return node
}

//顺序打印链表
func (linkList *DuplexLinkList) Println(){
	if linkList.Size==0 {
		return
	}
	node := linkList.Head
	fmt.Println(node.Data)
	for i:=uint(1);i<linkList.Size;i++{
		node = node.NextData
		fmt.Println(node.Data)
	}
}

//倒序打印链表
func (linkList *DuplexLinkList) ReversePrintln(){
	if linkList.Size==0 {
		return
	}
	if linkList.Size==1 {
		fmt.Println(linkList.Head.Data)
	}else{
		node := linkList.Tail
		fmt.Println(node.Data)
		for i:=linkList.Size;i>1 ;i-- {
			node = node.PreData
			fmt.Println(node.Data)
		}
	}
}
